/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.base.controller;

import com.xy.biz.base.client.GoodsClient;
import com.xy.biz.base.domain.converter.GoodsConverter;
import com.xy.biz.base.domain.enums.ProductionDateUnitEnum;
import com.xy.biz.base.domain.enums.QualityGuaranteePeriodUnitEnum;
import com.xy.biz.base.domain.query.GoodsQuery;
import com.xy.biz.base.domain.req.*;
import com.xy.biz.base.domain.resp.GetGoodsResponse;
import com.xy.biz.base.domain.resp.ListDictItemResponse;
import com.xy.biz.base.service.DictService;
import com.xy.biz.base.service.GoodsService;
import com.xy.lang.domain.KeyValue;
import com.xy.lang.domain.Page;
import com.xy.lang.domain.Result;
import com.xy.lang.enums.ApplyStatusEnum;
import com.xy.lang.util.EnumUtils;
import com.xy.lang.validation.SaveChecks;
import com.xy.lang.validation.UpdateChecks;
import com.xy.lang.validation.annotation.Validatable;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 *
 *
 * @author zgy
 * @date 2021-9-22
 */
@Api(tags = "货品服务")
@Slf4j
@RestController
@RequestMapping("/api/base/goods")
public class GoodsController implements GoodsClient {

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private DictService dictService;

    @Validatable(groups = {SaveChecks.class})
    @PostMapping(value = "/save")
    public Result<?> saveGoods(@RequestBody SaveGoodsRequest request) {
        return goodsService.saveGoods(GoodsConverter.toBO(request));
    }

    @Validatable(groups = {SaveChecks.class})
    @PostMapping(value = "/save_all")
    public Result<?> saveAllGoods(@RequestBody Collection<SaveGoodsRequest> collection) {
        return goodsService.saveAllGoods(GoodsConverter.toBO(collection));
    }

    @Validatable(groups = {UpdateChecks.class})
    @PostMapping(value = "/update")
    public Result<?> updateGoods(@RequestBody SaveGoodsRequest request) {
        return goodsService.updateGoods(GoodsConverter.toBO(request));
    }

    @Validatable
    @PostMapping(value = "/delete")
    public Result<?> deleteGoods(@RequestBody GetGoodsRequest request) {
        return goodsService.deleteGoods(request.getGoodsId());
    }

    @Validatable
    @PostMapping(value = "/get")
    @Override
    public Result<GetGoodsResponse> getGoods(@RequestBody GetGoodsRequest request) {
        return Result.success(GoodsConverter.toResponse(goodsService.getGoods(request.getGoodsId())));
    }

    @PostMapping(value = "/get_by_code")
    @Override
    public Result<GetGoodsResponse> getGoodsByCode(@RequestBody ListGoodsByCodeRequest request) {
        return Result.success(GoodsConverter.toResponse(
                goodsService.getGoodsByCode(request.getGoodsCode(), request.getStatus())));
    }

    @PostMapping(value = "/get_by_full_code")
    @Override
    public Result<GetGoodsResponse> getGoodsByFullCode(@RequestBody ListGoodsByFullCodeRequest request) {
        return Result.success(GoodsConverter.toResponse(
                goodsService.getGoodsByFullCode(request.getGoodsFullCode(), request.getStatus())));
    }

    @PostMapping(value = "/list_by_ids")
    @Override
    public Result<List<GetGoodsResponse>> listGoodsById(@RequestBody Collection<Long> collection) {
        return Result.success(GoodsConverter.toResponse(goodsService.listGoodsById(collection)));
    }

    @PostMapping(value = "/list")
    @Override
    public Result<List<GetGoodsResponse>> listGoods(@RequestBody ListGoodsRequest request) {
        return Result.success(GoodsConverter.toResponse(goodsService.listGoods(GoodsConverter.toQuery(request))));
    }

    @PostMapping(value = "/list_by_code")
    @Override
    public Result<List<GetGoodsResponse>> listGoodsByCode(@RequestBody ListGoodsByCodeRequest request) {
        return Result.success(GoodsConverter.toResponse(
                goodsService.listGoodsByCode(request.getGoodsCode(),
                        request.getStatus(),
                        request.getFuzzyFlag() == null ? false : request.getFuzzyFlag().booleanValue())));
    }

    @PostMapping(value = "/list_by_full_code")
    @Override
    public Result<List<GetGoodsResponse>> listGoodsByFullCode(@RequestBody ListGoodsByFullCodeRequest request) {
        return Result.success(GoodsConverter.toResponse(
                goodsService.listGoodsByFullCode(request.getGoodsFullCode(),
                        request.getStatus(),
                        request.getFuzzyFlag() == null ? false : request.getFuzzyFlag().booleanValue())));
    }

    @PostMapping(value = "/list_by_abbr")
    @Override
    public Result<List<GetGoodsResponse>> listGoodsByAbbr(@RequestBody ListGoodsByAbbrRequest request) {
        return Result.success(GoodsConverter.toResponse(
                goodsService.listGoodsByAbbr(request.getGoodsAbbr(),
                        request.getStatus(),
                        request.getFuzzyFlag() == null ? false : request.getFuzzyFlag().booleanValue())));
    }

    @PostMapping(value = "/page")
    @Override
    public Result<Page<GetGoodsResponse>> pageGoods(@RequestBody ListGoodsRequest request) {
        GoodsQuery query = GoodsConverter.toQuery(request);
        List<GetGoodsResponse> list = GoodsConverter.toResponse(goodsService.listGoods(query));
        int count = goodsService.countGoods(query);
        return Result.success(new Page<>(list, count));
    }

    @PostMapping(value = "/get_category")
    @Override
    public Result<Map<String, Integer>> mapCategory(@RequestBody Collection<String> goodsCodeCollection) {
        return Result.success(goodsService.mapCategory(goodsCodeCollection));
    }

    @Override
    public String getPrimitiveGoodsCode(String goodsCode) {
        return goodsService.getPrimitiveGoodsCode(goodsCode);
    }

    @GetMapping(value = "/list_pre_options")
    public Result<Map<String, List>> listPreOptions() {
        Map<String, List> map = new HashMap<>();
        map.put("status", EnumUtils.toKeyValueList(ApplyStatusEnum.values(),
                (e) -> ((ApplyStatusEnum)e).getName()));
        map.put("qualityGuaranteePeriodUnit", EnumUtils.toKeyValueList(QualityGuaranteePeriodUnitEnum.values(),
                (e) -> ((QualityGuaranteePeriodUnitEnum)e).getName()));
        map.put("productionDateUnit", EnumUtils.toKeyValueList(ProductionDateUnitEnum.values(),
                (e) -> ((ProductionDateUnitEnum)e).getName()));
        List<ListDictItemResponse> dictList = dictService.listDictItem(
                ListDictItemRequest.builder().pageSize(1000).dictGroupCodes(
                        Arrays.asList("goods_category", "goods_unit", "goods_storage", "goods_delivery")).build());
        if (!CollectionUtils.isEmpty(dictList)) {
            List<KeyValue<String, String>> goodsCategoryList = new ArrayList<>();
            List<KeyValue<String, String>> goodsUnitList = new ArrayList<>();
            List<KeyValue<String, String>> goodsStorageList = new ArrayList<>();
            List<KeyValue<String, String>> goodsDeliveryList = new ArrayList<>();
            dictList.forEach(e -> {
                if("goods_category".equals(e.getDictGroupCode())) {
                    goodsCategoryList.add(new KeyValue<>(e.getDictCode(), e.getDictValue()));
                } else if("goods_unit".equals(e.getDictGroupCode())) {
                    goodsUnitList.add(new KeyValue<>(e.getDictValue(), e.getDictValue()));
                } else if("goods_storage".equals(e.getDictGroupCode())) {
                    goodsStorageList.add(new KeyValue<>(e.getDictCode(), e.getDictValue()));
                } else if("goods_delivery".equals(e.getDictGroupCode())) {
                    goodsDeliveryList.add(new KeyValue<>(e.getDictCode(), e.getDictValue()));
                }
            });
            map.put("goodsCategory", goodsCategoryList);
            map.put("goodsUnit", goodsUnitList);
            map.put("goodsStorage", goodsStorageList);
            map.put("goodsDelivery", goodsDeliveryList);
        }
        return Result.success(map);
    }

}
